package utils;

import bean.Content;
import dao.ApiDao;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.channels.FileChannel;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.zip.GZIPInputStream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class FileUtils {
	private static final Logger logger = LoggerFactory.getLogger(FileUtils.class);
	public static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";

	
	/** 
	* @Title: importFile 
	* @Description: TODO(这里用一句话描述这个方法的作用) 
	* @param @param file
	* @param @return    设定参数 
	* @return List<Content>    返回类型 
	* @throws 
	* @author undoner@gmail.com 
	* @date 2017年1月23日 下午12:59:25 
	*/
	public static List<Content> importFile(File file){
		List<Content> dataList=new ArrayList<Content>();

		BufferedReader br=null;
		try {
			br = new BufferedReader(new FileReader(file));
			String lineContent = "";
			long lineNo=1;
			while ((lineContent = br.readLine()) != null) {
				if(lineContent.startsWith("Program")){
					continue;
				}
				Content content = new Content();
				content.setLineNo(lineNo++);
				content.setLineContent(lineContent);
				dataList.add(content);
//				System.out.println("lineContent:"+lineContent);
			}
		}catch (Exception e) {
		}finally{
			if(br!=null){
				try {
					br.close();
					br=null;
				} catch (IOException e) {
					logger.error(e.getMessage());
				}
			}
		}

		return dataList;
	}

	/** 
	* @Title: searchKey 
	* @Description: TODO(倒叙搜索指定关键词) 
	* @param @param dataList
	* @param @param SearchKey
	* @param @param upLineConunt
	* @param @param downLineCount
	* @param @param limit
	* @param @return    设定参数 
	* @return List<Content>    返回类型 
	* @throws 
	* @author undoner@gmail.com 
	* @date 2017年1月23日 下午12:59:35 
	*/
	public static List<Content> searchKey(List<Content> dataList,String SearchKey,int upLineConunt,int downLineCount,int limit){
		final String AND="and:";
		final String OR="or:";
		
		//默认关键词  AND 检索
		Boolean isAnd = true;
		
		//根据请求参数前缀判断：ad:表示 and   or:表示 or
		if(SearchKey.startsWith(AND)){
			isAnd = true;
			//去掉参数前缀
			SearchKey = SearchKey.substring(AND.length(), SearchKey.length());
			logger.debug("SearchKey:"+SearchKey);
		}else if(SearchKey.startsWith(OR)){
			isAnd = false;
			//去掉参数前缀
			SearchKey = SearchKey.substring(OR.length(), SearchKey.length());
			logger.debug("SearchKey:"+SearchKey);
		}
		
		//,号分隔符 格式化 参数 字符串 至 数组
		String keyArray [] = SearchKey.split(",");
		
		List<Content> returnDataList=new ArrayList<Content>();
		int countLimit =1 ;
		for(int i=dataList.size()-1;i>=0;i--){
			Content content = dataList.get(i);
			boolean isContains=false;
			
			if(isAnd){
				//AND 检错:必须满足所有关键词匹配 即isContains=true
				int countContains=0;
				for(String searchStr :keyArray){
					if(content.getLineContent().contains(searchStr)){
						countContains++;
					}
				}
				//需满足匹配countContains次数 等于关键词个数,即全部匹配到
				//logger.debug("LineNo:"+content.getLineNo()+",countContains:"+countContains+",keyArray.length:"+keyArray.length);
				if(countContains==keyArray.length){
					isContains=true;
				}
				
			}else{
				//OR 检错:满足任意一个关键词匹配 即 isContains=true
				for(String searchStr :keyArray){
					if(content.getLineContent().contains(searchStr)){
						isContains=true;
						break;
					}
				}
			}
			
			//isContains = true
			if(isContains){
				for(int upLine =upLineConunt ;upLine>0  ; upLine--){
					if(i-upLine>=0){
						returnDataList.add(dataList.get(i-upLine));
						logger.debug(dataList.get(i-upLine).getLineNo()+":"+dataList.get(i-upLine).getLineContent());
					}
				}
				logger.debug(content.getLineNo()+":"+content.getLineContent());
				
				for(int downLine =1 ;downLine<=downLineCount ; downLine++){
					if(i+downLine<dataList.size()){
						returnDataList.add(dataList.get(i+downLine));
						logger.debug(dataList.get(i+downLine).getLineNo()+":"+dataList.get(i+downLine).getLineContent());
					}
				}
				
				returnDataList.add(content);
				
				if(countLimit>=limit){
					break;
				}
				
				countLimit++;

			}
		}
		return returnDataList;
	}
	
	public static void main(String args[]) throws  Exception{
		String fileUrl = "E:\\logs.txt";
		File file = new File(fileUrl);
		FileUtils fileU = new FileUtils();
		
		List<Content> dataList=new ArrayList<Content>();
		dataList=fileU.importFile(file);
//		searchKey(dataList,"systemEnvironment");
	}
	
	public boolean format(String srcScreenShot, long recordStartTimeLong){
		List<File> fileList = getFileList(srcScreenShot);
		logger.debug("FileUtils.format() srcScreenShot : " + srcScreenShot + " , recordStartTimeLong : " + recordStartTimeLong + " , Image total：" + fileList.size());

		for (int i = 0; i < fileList.size(); i++) {
			if (fileList.get(i).isFile()) {
				String fileName = fileList.get(i).getName();
				String fileNamePostfix = "";
				if (!fileName.endsWith((".jpg"))&&!fileName.endsWith((".bmp"))) {
					continue;
				}
				if (fileName.indexOf(".") >= 0) {
					fileNamePostfix = fileName.substring(fileName.lastIndexOf("."), fileName.length());
					fileName = fileName.substring(0, fileName.lastIndexOf("."));
				}
				String newFileName = srcScreenShot + recordStartTimeLong + fileNamePostfix;
				
				//System.out.println("file：" + fileList.get(i)+ ",fileName:"+ fileName + ",newfileName:"+ newFileName+",recordStartTimeLong:"+recordStartTimeLong);
				recordStartTimeLong=recordStartTimeLong+500;
				fileList.get(i).renameTo(new File(newFileName)); // 改名
			}
			if (fileList.get(i).isDirectory()) {
				logger.debug("文件夹：" + fileList.get(i));
			}
		}
		return true;

	}

	public static List<File> getFileList(String srcScreenShot){
		File file = new File(srcScreenShot);
		File[] tempList = file.listFiles();

		if(tempList==null||tempList.length==0){
			return null;
		}
		List<File> fileList = new ArrayList<File>();
		for (File f : tempList) {
			fileList.add(f);
		}
		Collections.sort(fileList, new Comparator<File>() {
			@Override
			public int compare(File o1, File o2) {
				if (o1.isDirectory() && o2.isFile())
					return -1;
				if (o1.isFile() && o2.isDirectory())
					return 1;
				return o1.getName().compareTo(o2.getName());
			}
		});

		return fileList;
	}

	


	/**
	 * 从网络Url中下载文件
	 *
	 * @param elementId
	 * @param elementTitle
	 * @param elementUrl
	 *
	 */
	public boolean downLoadFile(String fileUrl,String elementId, String elementTitle, String webUrl) {
		URL url = null;
		String urlStr =webUrl;
		String fileName = elementTitle;
		try {
			url = new URL(urlStr);
			HttpURLConnection conn = (HttpURLConnection) url.openConnection();
			// 设置超时间为3秒
			conn.setConnectTimeout(10 * 1000);
			// 防止屏蔽程序抓取而返回403错误
			conn.setRequestProperty("User-Agent",
					"Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");

			// 得到输入流
			InputStream inputStream = conn.getInputStream();
			// 获取自己数组
			byte[] getData = readInputStream(inputStream);

			// 文件保存位置
			File saveDir = new File(fileUrl);
			if (!saveDir.exists()) {
				saveDir.mkdir();
			}
			File file = new File(saveDir + File.separator + fileName);
			FileOutputStream fos = new FileOutputStream(file);
			fos.write(getData);
			if (fos != null) {
				fos.close();
			}
			if (inputStream != null) {
				inputStream.close();
			}
			return true;
		} catch (Exception e) {
			// TODO Auto-generated catch block
			System.err.println(url + " download failed!"+e.getMessage());
			return false;
		}

	}

	/**
	 * 从输入流中获取字节数组
	 *
	 * @param inputStream
	 * @return
	 * @throws IOException
	 */
	public  byte[] readInputStream(InputStream inputStream)
			throws IOException {
		byte[] buffer = new byte[1024];
		int len = 0;
		ByteArrayOutputStream bos = new ByteArrayOutputStream();
		while ((len = inputStream.read(buffer)) != -1) {
			bos.write(buffer, 0, len);
		}
		bos.close();
		return bos.toByteArray();
	}

	public static String dateTransformBetweenTimeZone(Date sourceDate,
			DateFormat formatter, TimeZone sourceTimeZone,
			TimeZone targetTimeZone) {
		Long targetTime = sourceDate.getTime() - sourceTimeZone.getRawOffset()
				+ targetTimeZone.getRawOffset();
		return FileUtils.getTime(new Date(targetTime), formatter);
	}

	public static String getTime(Date date, DateFormat formatter) {
		return formatter.format(date);
	}

	// 时区转换1
	public static void setTimeZone() {
		DateFormat formatter = new SimpleDateFormat(DATE_FORMAT);
		Date date = Calendar.getInstance().getTime();
		System.out.println(date);
		TimeZone srcTimeZone = TimeZone.getTimeZone("GMT+8");
		TimeZone destTimeZone = TimeZone.getTimeZone("GMT-8");
		System.out.println(FileUtils.dateTransformBetweenTimeZone(date,
				formatter, srcTimeZone, destTimeZone));
	}

	// 时区转换2
	public static void setTimeZone2() {
		// 当前系统默认时区的时间：
		Calendar calendar = new GregorianCalendar();
		System.out.print("时区：" + calendar.getTimeZone().getID() + "  ");
		System.out.println("时间：" + calendar.get(Calendar.HOUR_OF_DAY) + ":"
				+ calendar.get(Calendar.MINUTE));
		// 美国洛杉矶时区
		TimeZone tz = TimeZone.getTimeZone("America/Los_Angeles");
		// 时区转换
		calendar.setTimeZone(tz);
		System.out.print("时区：" + calendar.getTimeZone().getID() + "  ");
		System.out.println("时间：" + calendar.get(Calendar.HOUR_OF_DAY) + ":"
				+ calendar.get(Calendar.MINUTE));
	}

	//时区转换3
	public static long dateFormat(String dateTime, String timezoneId) throws ParseException {
		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		dateFormat.setTimeZone(TimeZone.getTimeZone("GMT-8"));
		String recordStartTimeStr = dateFormat.parse(dateTime).toString();
		System.out.println("recordStartTimeStr:" + recordStartTimeStr);
		long recordStartTimeLong = dateFormat.parse(dateTime).getTime();
		System.out.println("time2:" + recordStartTimeLong);
		return recordStartTimeLong;
	}

	public static void deleteDirFile(String sDirFilePath)
	{
		if (sDirFilePath != null && !sDirFilePath.trim().equals(""))
		{
			File tDirFile = new File(sDirFilePath);
			if (tDirFile.exists())
			{
				if (tDirFile.isDirectory())
				{
					File[] arrFiles = tDirFile.listFiles();
					//循环删除目录下的子目录
					for (int i = 0; i < arrFiles.length; i++)
					{
						deleteDirFile(arrFiles[i].getAbsolutePath());
					}
					arrFiles = null;
					//当目录下的所有删除后, 再把本目录删除
					tDirFile.delete();
				}
				else
				{
					tDirFile.delete();
				}
			}
			tDirFile = null;
		}
	}

	public static void deleteFilesByDirName(String sDirFilePath)
	{
		if (sDirFilePath != null && !sDirFilePath.trim().equals(""))
		{
			File tDirFile = new File(sDirFilePath);
			if (tDirFile.exists())
			{
				if (tDirFile.isDirectory())
				{
					File[] arrFiles = tDirFile.listFiles();
					//循环删除目录下的子目录
					for (int i = 0; i < arrFiles.length; i++)
					{
						deleteDirFile(arrFiles[i].getAbsolutePath());
					}
					arrFiles = null;
				}
			}
			tDirFile = null;
		}
	}

	/**
	 * 删除单个文件
	 * @param   sPath    被删除文件的文件名
	 * @return 单个文件删除成功返回true，否则返回false
	 */
	public static boolean deleteFile(String sPath) {
		boolean flag = false;
		File file = new File(sPath);
		// 路径为文件且不为空则进行删除
		if (file.isFile() && file.exists()) {
			file.delete();
			flag = true;
		}
		return flag;
	}

	//将本次任务待检测的element元素id，写入recordId.txt文件
	public void writeElementIds(List<Long> elementIds,String screenAlgorithmTxtPathStr){
		File file = new File(screenAlgorithmTxtPathStr);
		FileWriter fw = null;
		BufferedWriter writer = null;
		try {
			fw = new FileWriter(file,true);
			writer = new BufferedWriter(fw);
			for(int i=0;i<elementIds.size();i++){
				if(i<elementIds.size()-1){
					writer.write(elementIds.get(i).toString()+",");
				}else{
					writer.write(elementIds.get(i).toString());
				}

			}
			writer.newLine();//换行
			writer.flush();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}catch (IOException e) {
			e.printStackTrace();
		}finally{
			try {
				writer.close();
				fw.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	public static boolean readBeResultFileIsEnd(String url){
		RandomAccessFile rf = null;
//		System.out.println("3"+new Date().getTime());
		try {
			rf = new RandomAccessFile(url, "r");
			long len = rf.length();
			long start = rf.getFilePointer();
			long nextend = start + len - 1;
			String line = "";
			rf.seek(nextend);
			int c = -1;
			int t = 0;
			while (nextend > start) {
				c = rf.read();
				if (c == '\n' || c == '\r') {
					line = rf.readLine();
					t++;
					if (t >= 1 && line != null) {
						if(line.equals("END")){
							System.out.println("line END: "+line);
							return true;
						}

					}
					nextend--;
				}
				nextend--;
				rf.seek(nextend);
				if (nextend == 0) {
				// 当文件指针退至文件开始处，输出第一行
					System.out.println("line 1: "+rf.readLine());
				}
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
//			System.out.println(new Date().getTime());
			try {
				if (rf != null)
					rf.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return false;
	}

	
	public static void writeToBeResultLocalFile(List<Content> beResultsList,String url,String newRecordSuspectId){
		File file = new File(url);
		FileWriter fw = null;
		BufferedWriter writer = null;
		try {
			fw = new FileWriter(file,true);
			writer = new BufferedWriter(fw);
			writer.write("recordSuspect_id new_recordSuspect_id screenshot_offset element_id coordinate detect position user_id");
			writer.newLine();//换行
			for(Content content:beResultsList) {
				writer.write(content.getLineContent());
				writer.newLine();//换行
			}
			writer.newLine();//换行
			writer.flush();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}catch (IOException e) {
			e.printStackTrace();
		}finally{
			try {
				writer.close();
				fw.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}


	public static void nioTransferCopy(String sourceStr, String targetStr) {
		File source =new File(sourceStr);
		File target =new File(targetStr);
		if(!target.getParentFile().exists()){
			target.getParentFile().mkdirs();
		}
		FileChannel in = null;
		FileChannel out = null;
		FileInputStream inStream = null;
		FileOutputStream outStream = null;
		try {
			inStream = new FileInputStream(source);
			outStream = new FileOutputStream(target);
			in = inStream.getChannel();
			out = outStream.getChannel();
			in.transferTo(0, in.size(), out);
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try{
				inStream.close();
				in.close();
				outStream.close();
				out.close();
			}catch (IOException e) {
				e.printStackTrace();
			}

		}
	}
	
	private void writeToFile(InputStream inputStream, File file) throws IOException {
		byte[] temp = new byte[1024];
		int readSize;
		FileOutputStream fileOutputStream = new FileOutputStream(file);
		try {
			while ((readSize = inputStream.read(temp)) > 0) {
				fileOutputStream.write(temp, 0, readSize);
			}
		} finally {
			fileOutputStream.flush();
			fileOutputStream.close();
		}
	}



	public static String formatFileName(String name) {
		if (name == null) {
			return "";
		}
		name = name.replaceAll("[^A-Za-z0-9._-]", "");
		return name;
	}






	

}